package com.gitee.wsl.ext.bitcode


infix fun ByteArray.xor(other: ByteArray): ByteArray {
    if (this.size != other.size)
        throw IllegalArgumentException("ByteArray size not equal")

    val result = ByteArray(this.size)
    for (i in this.indices) {
        result[i] = (this[i].toInt() xor other[i].toInt()).toByte()
    }

    return result
}

infix fun IntArray.xor(other: IntArray): IntArray {
    if (this.size != other.size)
        throw IllegalArgumentException("IntArray size not equal")

    val result = IntArray(this.size)
    for (i in this.indices) {
        result[i] = this[i] xor other[i]
    }

    return result
}

infix fun LongArray.xor(other: LongArray): LongArray {
    if (this.size != other.size)
        throw IllegalArgumentException("LongArray size not equal")

    val result = LongArray(this.size)
    for (i in this.indices) {
        result[i] = this[i] xor other[i]
    }

    return result
}

infix fun List<Byte>.xor(other: List<Byte>): MutableList<Byte> {
    if (this.size != other.size)
        throw IllegalArgumentException("ByteArray size not equal")

    val result = ArrayList<Byte>(this.size)
    for (i in this.indices) {
        result.add((this[i].toInt() xor other[i].toInt()).toByte())
    }

    return result
}

fun xor(len: Int, x: ByteArray, y: ByteArray, z: ByteArray) {
    for (i in 0..<len) {
        z[i] = (x[i].toInt() xor y[i].toInt()).toByte()
    }
}

fun xor(len: Int, x: ByteArray, xOff: Int, y: ByteArray, yOff: Int, z: ByteArray, zOff: Int) {
    for (i in 0..<len) {
        z[zOff + i] = (x[xOff + i].toInt() xor y[yOff + i].toInt()).toByte()
    }
}


/**
 * Xor x with z0 and save result into both Z0 and Z1
 * z0 = z1 = X xor Z0
 * @param len length
 * @param x
 * @param xOff
 * @param z0
 * @param z0Off
 * @param z1
 * @param z1Off
 */
fun xorTee(len: Int, x: ByteArray, xOff: Int, z0: ByteArray, z0Off: Int, z1: ByteArray, z1Off: Int) {
    for (i in 0..<len) {
        z1[z1Off + i] = (x[xOff + i].toInt() xor z0[z0Off + i].toInt()).toByte()
        z0[z0Off + i] = z1[z1Off + i]
    }
}


fun xorTo(len: Int, x: ByteArray, z: ByteArray) {
    for (i in 0..<len) {
        z[i] = (z[i].toInt() xor x[i].toInt()).toByte()
    }
}

fun xorTo(len: Int, x: ByteArray, xOff: Int, z: ByteArray, zOff: Int) {
    for (i in 0..<len) {
        z[zOff + i] = (z[zOff + i].toInt() xor x[xOff + i].toInt()).toByte()
    }
}
